home *** CD-ROM | disk | FTP | other *** search
/ Gigantic Games 2 / Gigantic Games 2.iso / pc / _z_ / zorkmachine / zbios.c < prev    next >
C/C++ Source or Header  |  1994-12-23  |  23KB  |  1,481 lines

  1. /*:ts=8
  2. *    @(#)zbios.c    2.24
  3. *    Basic input/output System for ZMACHINE
  4. *    all machine dependent functions are collected
  5. *    in this file.
  6. */
  7.  
  8. #include    <fcntl.h>
  9. #include    <ctype.h>
  10. #ifdef    OSK
  11. #include    <modes.h>
  12. #endif
  13. #include    "zmachine.h"
  14. #include    "keys.h"
  15.  
  16. #ifdef AMIGA
  17. #include <libraries/iffparse.h>
  18. #include <clib/iffparse_protos.h>
  19.  
  20. #include <stdlib.h>
  21.  
  22. extern long StdOut;
  23.  
  24. char *sysname = "Amiga";
  25. int con_is_open;
  26.  
  27. #endif    /* AMIGA */
  28.  
  29. #ifdef GEMDOS
  30. char    *sysname = "Atari ST";
  31.  
  32. #include <sys\osbind.h>
  33. #endif
  34.  
  35. #if defined(unix) || defined(OSK)
  36. #ifdef unix
  37. char    *sysname = "u**x";
  38.  
  39. #include <sgtty.h>
  40. #include <signal.h>
  41. #include <sys/types.h>
  42.  
  43. struct sgttyb otermio,ntermio;
  44. #endif
  45. #ifdef OSK
  46. char    *sysname = "OS9/68000";
  47.  
  48. #include <sgstat.h>
  49. #define    fputc(a,b)    putc(a,b)
  50. #define gtty(FD,ADR)     getstat(0,FD,ADR)
  51. #define stty(FD,ADR)     setstat(0,FD,ADR)
  52. #define CHRAW(X)    chraw( & X)
  53. struct sgbuf nstate, ostate;
  54.  
  55. #define PC PC_
  56. int ospeed = 0;
  57.  
  58. chraw(x)
  59. struct sgbuf *x;
  60. {
  61.     x->sg_case = 0;
  62.     x->sg_backsp = 0;
  63.     x->sg_echo = 0;
  64.     x->sg_alf = 0;
  65.     x->sg_pause = 0;
  66.     x->sg_bspch = 0x80;
  67.     x->sg_dlnch = 0x80;
  68.     x->sg_eorch = 0x80;
  69.     x->sg_eofch = 0x80;
  70.     x->sg_rlnch = 0x80;
  71.      x->sg_dulnch = 0x80;
  72.     x->sg_psch = 0x80;
  73.     x->sg_kbich = 0x80;
  74.     x->sg_kbach = 0x80;
  75.     x->sg_bsech = 0x80;
  76.     x->sg_bellch = 0x80;
  77.     x->sg_tabcr = 0x80;
  78.     x->sg_xon = 0x11;
  79.     x->sg_xoff = 0x13;
  80. }
  81. #endif
  82.  
  83. char tcapbuf[1024];
  84. char *CM = NULL, *CL = NULL, *BC = NULL, *UP = NULL, *DL = NULL, *TI = NULL, *TE = NULL, *SE = NULL, *SO = NULL, PC = '\0', *VS = NULL, *VE = NULL;
  85. char *KS = NULL, *KE = NULL;
  86.  
  87.  
  88. struct fkencode
  89.     {
  90.         struct fkencode *nextchar;    /* next char in string */
  91.         struct fkencode *nextstring;  /* next string         */
  92.         int fkc;              /* current char
  93.                              > 0x100 = return    */
  94.     } *fkroot = NULL;
  95.  
  96. struct
  97.     {
  98.         char *name;
  99.         int code;
  100.     } keylist[] = {
  101.         { "kl", CLEFT },
  102.         { "kr", CRIGHT },
  103.         { "ku", CUP },
  104.         { "kd", CDOWN },
  105.         { "kb", BACKDEL },
  106.  
  107.         { "k0", FSTART + F01 },
  108.         { "k1", FSTART + F02 },
  109.         { "k2", FSTART + F03 },
  110.         { "k3", FSTART + F04 },
  111.         { "k4", FSTART + F05 },
  112.         { "k5", FSTART + F06 },
  113.         { "k6", FSTART + F07 },
  114.         { "k7", FSTART + F08 },
  115.         { "k8", FSTART + F09 },
  116.         { "k9", FSTART + F10 },
  117.         { NULL, 0 }
  118.     };
  119.  
  120. struct fkencode *insertc(fk, c)
  121. struct fkencode *fk; int c;
  122. {
  123.     if (!fk)
  124.     {
  125.         if (!(fk = (struct fkencode *)malloc(sizeof(struct fkencode))))
  126.             no_mem_error();
  127.         fk->nextchar = fk->nextstring = NULL;
  128.         fk->fkc = c;
  129.         return(fk);
  130.     }
  131.     else
  132.     {
  133.         if (fk->fkc == c)
  134.             return(fk);
  135.         else
  136.         {
  137.             if (!fk->nextstring)
  138.             {
  139.                 fk->nextstring = insertc(NULL, c);
  140.                 fk = fk->nextstring;
  141.             }
  142.             else
  143.                 fk = insertc(fk->nextstring, c);
  144.  
  145.             return(fk);
  146.         }
  147.     }
  148. }
  149.  
  150. struct fkencode *insertkey(fk, s, c)
  151. struct fkencode *fk; char *s; int c; 
  152. {
  153.     struct fkencode *root;
  154.  
  155.     if (fk)
  156.     {
  157.         root = fk;
  158.         fk = insertc(fk, *s++);
  159.     }
  160.     else
  161.         root = fk = insertc(NULL, *s++);
  162.  
  163.     while(*s)
  164.     {
  165.         if (fk->nextchar)
  166.             fk = insertc(fk->nextchar, *s++);
  167.         else
  168.         {
  169.             fk->nextchar = insertc(NULL, *s++);
  170.             fk = fk->nextchar;
  171.         }
  172.     }
  173.  
  174.     fk->nextchar = insertc(NULL, c);
  175.     return(root);
  176. }
  177. #endif
  178.  
  179.  
  180. int    story    = -1;
  181. int    save    = -1;
  182.  
  183. struct    {
  184.         int x, y, lline, lchar;
  185.     } con;
  186.  
  187. struct dev *screen;
  188.  
  189. void    icon_str();
  190. void    icon_chr();
  191. /*
  192. *    long random()    -    return a random number (range 0 - min 0x7fff)
  193. */
  194.  
  195. long zrandom()
  196. {
  197. #ifdef AMIGA
  198.     static int init = 1;
  199.     if (init)
  200.     {
  201.         init = 0;
  202.         srand((int)time(NULL));
  203.     }
  204.     return rand();
  205. #endif
  206. #ifdef GEMDOS
  207.     return(Random());
  208. #endif
  209. #if defined(unix) || defined(OSK)
  210.     extern void srand();
  211.     extern long rand();
  212.     extern long time();
  213.  
  214.     static int init = 1;
  215.  
  216.     if (init)
  217.     {
  218.         init = 0;
  219.         srand((int)time(NULL));
  220.     }
  221.  
  222.     return(rand());
  223. #endif
  224. }
  225.  
  226. /*
  227. *    con_flush()    -    flush the console output buffer
  228. */
  229.  
  230. void con_flush()
  231. {
  232. #if defined(unix) || defined(OSK) 
  233.     fflush(stdout);
  234. #endif
  235. }
  236.  
  237. /*
  238. *    con_chr(c)    -    output the single character c to
  239. *    char c;            the console-device
  240. */
  241.  
  242. void con_chr(c)
  243. char c;
  244. {
  245.     int x,y;
  246.     if (c == '\r')
  247.     {
  248.         gotoXY(0, con.y);
  249.         return;
  250.     }
  251.     else if (con.x++ >= con.lchar)
  252.     {
  253.         storeXY(&x, &y);
  254. #ifndef AMIGA
  255.         /* Is autmatically done by Amiga COnsole device */
  256.         con_crlf();
  257. #endif
  258.         if (y >= con.lline)
  259.             y = con.lline-1;
  260.         gotoXY(con.lchar, y);
  261. #ifdef AMIGA
  262.         cursorOFF();
  263.         ConPutC(c);
  264. #else
  265. #ifdef GEMDOS
  266.         Bconout(2,c);
  267. #else
  268.         putchar(c);
  269. #endif
  270. #endif
  271.         gotoXY(0,y+1);
  272. #ifdef AMIGA
  273.         cursorON();
  274. #endif
  275.     }
  276.     else
  277. #ifdef AMIGA
  278.         ConPutC(c);
  279. #else
  280. #ifdef GEMDOS
  281.         Bconout(2,c);
  282. #else
  283.         putchar(c);
  284. #endif
  285. #endif
  286. }
  287.  
  288. /*
  289. *    con_str1(p)        -    output a '\0' terminated string to
  290. *    char *p;            the console-device
  291. */
  292.  
  293. void con_str1(p)
  294. register char *p;
  295. #ifdef AMIGA
  296.     {
  297.     ConPutS((UBYTE *)p);
  298.  
  299.     con.x += strlen(p);
  300.     }
  301. #else
  302. {    while(*p)
  303.         con_chr(*p++);
  304. }
  305. #endif
  306.  
  307. /*
  308. *    con_str2(p,q)        -    output the string p with the
  309. *    char *p, *q;            endaddress q to the console-device
  310. *
  311. */
  312.  
  313. void con_str2(p,q)
  314. register char *p,*q;
  315. #ifdef AMIGA
  316.     {
  317.     ConPutS2((UBYTE *)p,(UBYTE *)q);
  318.     con.x += q - p;
  319.     }
  320. #else
  321. {
  322.     while(p < q)
  323.         con_chr(*p++);
  324. }
  325. #endif
  326.  
  327. /*
  328. *    con_crlf()        -    scroll all lines but first
  329. *                    status_len lines (if possible).
  330. *                    goto first column of next line.
  331. */
  332.  
  333. void con_crlf()
  334. {
  335.     extern int status_len;
  336. #if defined(unix) || defined(OSK) || defined(AMIGA)
  337.     int x,y;
  338. #endif
  339.     if (con.y >= con.lline)
  340.     {
  341. #ifdef AMIGA
  342.         storeXY(&x,&y);
  343.         cursorOFF();
  344.         gotoXY(0, status_len);
  345.         icon_str("\033[M");
  346.         x = 0; y = con.lline;
  347.         gotoXY(x,y);
  348.         cursorON();
  349. #endif
  350. #ifdef GEMDOS
  351.         icon_str("\033j\033f\033Y");
  352.         icon_chr(' ' + status_len);
  353.         icon_str(" \033M\033k\r\033e");
  354. #endif
  355. #if defined(unix) || defined(OSK)
  356.         storeXY(&x,&y);
  357.         cursorOFF();
  358.         if (DL)
  359.         {
  360.             gotoXY(0,status_len);
  361.             putpad(DL);
  362.         }
  363.         else
  364.         {
  365.             gotoXY(0, con.lline);
  366. #ifdef OSK
  367.             icon_str("\012");
  368. #else
  369.             icon_str("\n");
  370. #endif
  371.         }
  372.         x = 0;
  373.         gotoXY(x,y);
  374.         cursorON();
  375. #endif
  376.     }
  377.     else
  378.     {
  379. #ifdef OSK
  380.         icon_str("\015\012");
  381. #else
  382.         icon_str("\r\n");
  383. #endif
  384.         con.y++;
  385.     }
  386.     con.x = 0;
  387. }
  388.  
  389. /*
  390. *    reverseON()        -    turn reversemode on
  391. *    reverseOFF()        -    turn reversemode off
  392. */
  393.  
  394. void reverseON()
  395. {
  396. #ifdef AMIGA
  397.     icon_str("\033[7m");
  398. #endif
  399. #ifdef GEMDOS
  400.     icon_str("\033p");
  401. #endif
  402. #if defined(unix) || defined(OSK)
  403.     if (SO)  
  404.         putpad(SO);
  405. #endif
  406. }
  407.  
  408. void reverseOFF()
  409. {
  410. #ifdef AMIGA
  411.     icon_str("\033[0m");
  412. #endif
  413. #ifdef GEMDOS
  414.     icon_str("\033q");
  415. #endif
  416. #if defined(unix) || defined(OSK)
  417.     if (SE)
  418.         putpad(SE);
  419. #endif
  420. }
  421.  
  422. /*
  423. *    cursorON()        -    turn cursor on
  424. *    cursorOFF()        -    turn cursor off
  425. */
  426.  
  427. void cursorON()
  428. {
  429. #ifdef AMIGA
  430.     icon_str("\033[ p");
  431. #endif
  432. #ifdef GEMDOS
  433.     icon_str("\033e");
  434. #endif
  435. }
  436.  
  437. void cursorOFF()
  438. {
  439. #ifdef AMIGA
  440.     icon_str("\033[0 p");
  441. #endif
  442. #ifdef GEMDOS
  443.     icon_str("\033f");
  444. #endif
  445. }
  446.  
  447. /*
  448. *    cursorLEFT()        -    move cursor left (with wrap)
  449. */
  450.  
  451. void
  452. cursorLEFT()
  453. {
  454.     if (con.x)
  455.     {
  456. #ifdef AMIGA
  457.         icon_str("\33[D");
  458. #endif
  459. #ifdef GEMDOS
  460.         icon_chr(8);
  461. #endif
  462. #if defined(unix) || defined(OSK)
  463.         icon_str(BC);
  464. #endif
  465.         con.x--;
  466.     }
  467.     else
  468.         gotoXY(con.lchar, con.y - 1);
  469. }
  470.  
  471. /*
  472. *    gotoXY(x,y)        -    goto screen position x,y
  473. *    int x,y;
  474. */
  475.  
  476. void gotoXY(x,y)
  477. int x,y;
  478. {
  479. #ifdef AMIGA
  480.     char posstr[20];
  481.     sprintf(posstr,"\033[%d;%dH",y+1,x+1);
  482.     icon_str(posstr);
  483. #endif
  484. #ifdef GEMDOS
  485.     icon_str("\033Y");
  486.     icon_chr(' ' + y);
  487.     icon_chr(' ' + x);
  488. #endif
  489. #if defined(unix) || defined(OSK)
  490.     extern char *tgoto();
  491.     putpad(tgoto(CM, x, y));
  492. #endif
  493.     con.x = x;
  494.     con.y = y;
  495. }
  496.  
  497. /*
  498. *    storeXY(x,y)        -    store current cursor position to
  499. *    int *x, *y;            x and y
  500. */
  501.  
  502. void storeXY(x,y)
  503. int *x, *y;
  504. {
  505.     *x = con.x;
  506.     *y = con.y;
  507. }
  508.  
  509. /*
  510. *    int con_getc()    -        get a character from the console
  511. *                    handle special chars.
  512. */
  513.  
  514. #ifdef AMIGA
  515. int con_getc()
  516.     {
  517.     int c;
  518.     int test;
  519.     char csistr[256];
  520.     char *csipos;
  521.  
  522. RETRY:
  523.     csipos = csistr;
  524.  
  525.     c = ConGetC();
  526.  
  527.     switch (c) {
  528.         case 0x9b:
  529.             while (1) {
  530.                 test = ConGetC();
  531.                 *csipos++ = test;
  532.                 if (isalpha(test) || test == '|' || test == '~'
  533.                         || test == '@')
  534.                         break;
  535.                 }
  536.             *csipos = '\0';
  537.             if (strlen(csistr) == 1) {
  538.                 switch(*csistr) {
  539.                   case 'A':
  540.                     return (CUP);
  541.                   case 'B':
  542.                     return (CDOWN);
  543.                   case 'C':
  544.                     return (CRIGHT);
  545.                   case 'D':
  546.                     return (CLEFT);
  547.                   default:
  548.                     goto RETRY;
  549.                   }
  550.                 }
  551.             if (strlen(csistr) == 2) {
  552.                 switch(csistr[1]) {
  553.                   case 'A':
  554.                 if (*csistr == ' ')
  555.                   return (START);
  556.                     break;
  557.                   case '@':
  558.                 if (*csistr == ' ')
  559.                   return (END);
  560.                     break;
  561.                   case '~':
  562.                     if (*csistr >= '0' && *csistr <= '9')
  563.                   return (FSTART+csistr[0]-'0'+1);
  564.                 if (*csistr == '?') /* HELP */
  565.                   return (FPROG);
  566.                     break;
  567.                   }
  568.                 goto RETRY;
  569.                 }
  570.             if (strlen(csistr) == 3) {
  571.                 switch(csistr[2]) {
  572.                   case '~':
  573.                     if (*csistr == '1' && csistr[1] >= '0' 
  574.                     && csistr[1] <= '9')
  575.                   return (FSTART+csistr[1]-'0'+11);
  576.                     break;
  577.  
  578.                   case 'v':
  579.                     if(csistr[0] == '0' && csistr[1] == ' ')
  580.                     {
  581.                         STATIC UBYTE         Buffer[256];
  582.  
  583.                         extern UBYTE        *String;
  584.  
  585.                     struct IFFHandle    *Handle;
  586.                     LONG             Bytes = 0,Size = 255;
  587.  
  588.                     if(Handle = AllocIFF())
  589.                     {
  590.                         if(Handle -> iff_Stream = (ULONG)OpenClipboard(PRIMARY_CLIP))
  591.                         {
  592.                             InitIFFasClip(Handle);
  593.  
  594.                             if(!OpenIFF(Handle,IFFF_READ))
  595.                             {
  596.                                 if(!StopChunk(Handle,'FTXT','CHRS'))
  597.                                 {
  598.                                     if(!ParseIFF(Handle,IFFPARSE_SCAN))
  599.                                     {
  600.                                         struct ContextNode *ContextNode;
  601.  
  602.                                         if(ContextNode = CurrentChunk(Handle))
  603.                                         {
  604.                                             if(Size > ContextNode -> cn_Size)
  605.                                                 Size = ContextNode -> cn_Size;
  606.  
  607.                                             if(ReadChunkRecords(Handle,Buffer,Size,1))
  608.                                                 Bytes = Size;
  609.                                         }
  610.                                     }
  611.                                 }
  612.  
  613.                                 CloseIFF(Handle);
  614.                             }
  615.  
  616.                             CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  617.                         }
  618.  
  619.                         FreeIFF(Handle);
  620.                     }
  621.  
  622.                     if(Bytes)
  623.                     {
  624.                         WORD i;
  625.  
  626.                         Buffer[Bytes] = 0;
  627.  
  628.                         String = Buffer;
  629.  
  630.                         for(i = 0 ; i < Bytes ; i++)
  631.                             Buffer[i] = tolower(Buffer[i]);
  632.                     }
  633.                     }
  634.                   }
  635.                 goto RETRY;
  636.                 }
  637.             if (csistr[strlen(csistr)-1] == '|') {
  638.                 if (strncmp(csistr,"12",2)==0) {
  639.                     /* Get a window status report */
  640.                 ConPutS((UBYTE *)"\2330 q");
  641.                 goto RETRY;
  642.                 }
  643.                 }
  644.             if (csistr[strlen(csistr)-1] == 'r') {
  645.                 static int oldcols = 0;
  646.                 int cols, rows;
  647.                 sscanf(csistr,"1;1;%d;%d r",&rows,&cols);
  648.                 con.y = con.y + rows - screen->height;
  649.                 screen->width = cols;
  650.                 screen->height = rows;
  651.                 con.lline = rows - 1;
  652.                 con.lchar = cols - 1;
  653.  
  654.                 if(oldcols && oldcols < cols)
  655.                    ConPutS((STRPTR)"\f");
  656.  
  657.                 oldcols = cols;
  658.  
  659.                 output_status(NULL,NULL);
  660.  
  661.                 return 0;
  662.                 }
  663.  
  664.             goto RETRY;
  665.  
  666.         case 0x01:    /* CTRL-A */
  667.             return(START);
  668.  
  669.         case 0x1a:    /* CTRL-Z */
  670.             return(END);
  671.  
  672.         case 0x0c:    /* CTRL-L */
  673.             return(RETYPE);
  674.  
  675.         case 0x18:    /* CTRL-X */
  676.             return(CLEAR);
  677.  
  678.         case 0x09:    /* CTRL-I */
  679.             return(INSERT);
  680.  
  681.         case 0x08:
  682.             return(BACKDEL);
  683.  
  684.         case 0x7f:
  685.             return(FORWDEL);
  686.  
  687.         case 0x04:    /* CTRL-D */
  688.             return(FORWDEL);
  689.  
  690.         case 0x10:    /* CTRL-P */
  691.             return(FPROG);
  692.  
  693.         case 0x0d:
  694.             return(RETURN);
  695.  
  696.         default:
  697.             if(c > 127 || c < 0)
  698.                 goto RETRY;
  699.             return(tolower(c));
  700.         }
  701.     }
  702. #else
  703. #ifdef GEMDOS
  704. int con_getc()
  705. {
  706.     long c;
  707.     static int s = 16;
  708.     c = Bconin(2);
  709.     switch((int)(c >> s))        /* compiler error */
  710.     {
  711.         case 0x004b:
  712.             return(CLEFT);
  713.  
  714.         case 0x004d:
  715.             return(CRIGHT);
  716.  
  717.         case 0x0050:
  718.             return(CDOWN);
  719.  
  720.         case 0x0048:
  721.             return(CUP);
  722.  
  723.         case 0x0061:
  724.             return(RETYPE);
  725.  
  726.         case 0x0052:
  727.             return(INSERT);
  728.  
  729.         case 0x0073:
  730.             return(START);
  731.  
  732.         case 0x0074:
  733.             return(END);
  734.  
  735.         default:
  736.             if ((c >> s) > 0x003a && (c >> s) < 0x0045)
  737.                 return(FSTART + (c >> s) - 0x003b);
  738.  
  739.             switch((int)(c&0xff))
  740.             {
  741.                 case 0x01:
  742.                     return(START);
  743.  
  744.                 case 0x05:
  745.                     return(END);
  746.  
  747.                 case 0x19:
  748.                     return(RETYPE);
  749.  
  750.                 case 0x0b:
  751.                     return(KILL);
  752.  
  753.                 case 0x08:
  754.                     return(BACKDEL);
  755.  
  756.                 case 0x7f:
  757.                     return(FORWDEL);
  758.  
  759.                 case 0x04:
  760.                     return(FORWDEL);
  761.  
  762.                 case 0x02:
  763.                     return(CLEFT);
  764.  
  765.                 case 0x06:
  766.                     return(CRIGHT);
  767.  
  768.                 case 0x0e:
  769.                     return(CDOWN);
  770.  
  771.                 case 0x10:
  772.                     return(CUP);
  773.  
  774.                 case 0x09:
  775.                     return(FPROG);
  776.  
  777.                 case 0x0d:
  778.                     return(RETURN);
  779.  
  780.                 default:
  781.                     return(c&0xff);
  782.             }
  783.     }
  784. }
  785. #else
  786. int con_getc()
  787. {
  788.     char c;
  789. RETRY:
  790.     read(0, &c, 1);
  791.     c &= 0x7f;
  792.     for (fk = fkroot; fk;)
  793.     {
  794.         if (fk && c == fk->fkc)
  795.         {
  796.             fk = fk->nextchar;
  797.             if (fk && fk->fkc > 0x100)
  798.                 return(fk->fkc);
  799.             else
  800.             {
  801.                 read(0, &c, 1);
  802.                 c &= 0x7f;
  803.             }
  804.         }
  805.         else
  806.             fk = fk->nextstring;
  807.     }
  808.  
  809.     switch((int)(c&0xff))
  810.     {
  811.         case 0x18:
  812.             read(0, &c, 1);
  813.             c &= 0x0f;
  814.             if (c > 9)
  815.                 goto RETRY;
  816.             return(c + FSTART);
  817.  
  818.         case 0x01:
  819.             return(START);
  820.  
  821.         case 0x05:
  822.             return(END);
  823.  
  824.         case 0x19:
  825.             return(RETYPE);
  826.  
  827.         case 0x0b:
  828.             return(KILL);
  829.  
  830.         case 0x7f:
  831.             return(BACKDEL);
  832.  
  833.         case 0x08:
  834.             return(FORWDEL);
  835.  
  836.         case 0x04:
  837.             return(FORWDEL);
  838.  
  839.         case 0x02:
  840.             return(CLEFT);
  841.  
  842.         case 0x06:
  843.             return(CRIGHT);
  844.  
  845.         case 0x0e:
  846.             return(CDOWN);
  847.  
  848.         case 0x10:
  849.             return(CUP);
  850.  
  851.         case 0x09:
  852.             return(FPROG);
  853.  
  854.         case '\n':
  855. #ifndef OSK
  856.         case 0x0d:
  857. #endif
  858.             return(RETURN);
  859.  
  860.         default:
  861.             return(c&0xff);
  862.     }
  863. }
  864. #endif
  865. #endif
  866.  
  867. /*
  868. *    init_con()        -    initialize console
  869. *                    - clear screen
  870. *                    - goto last line on screen
  871. */
  872.  
  873. void init_con()
  874. {
  875.     int len;
  876.     int lines;
  877.     static int init=1;
  878. #if defined(unix) || defined(OSK)
  879.     char *getenv(), *tgetstr();
  880.     char *p, *t, *tv_stype;
  881.     int i;
  882.     void clean_up();
  883.     char tcbuf[1024];
  884. #endif
  885.  
  886. #ifdef AMIGA
  887.     if (init)
  888.     {
  889.         len = 80;
  890.         lines = 25;
  891.         con_is_open = 0;
  892.         if (!OpenConsoleStuff())
  893.             fatal("Can't open Window!",1);
  894.         con_is_open = 1;
  895.     }
  896. #endif
  897. #ifdef GEMDOS
  898.     if (Getrez())
  899.         len = 80;
  900.     else
  901.         len = 40;
  902.     lines = 25;
  903. #endif
  904.  
  905. #if defined(unix) || defined(OSK)
  906.     if (init)
  907.     {
  908. #ifdef unix
  909.         ioctl(0, TIOCGETP, &otermio);
  910.         ntermio = otermio;
  911.         ntermio.sg_flags |= RAW;
  912.         ntermio.sg_flags &= ~(ECHO|CRMOD);
  913.         ioctl(0, TIOCSETP, &ntermio);
  914. #endif
  915. #ifdef OSK
  916.         gtty(0, &ostate);
  917.         gtty(0, &nstate);
  918.         CHRAW(nstate);
  919.         stty(0, &nstate);
  920. #endif
  921.         if ((tv_stype = getenv("TERM")) == NULL)
  922.             fatal("Environment variable TERM not defined", NULL);
  923.  
  924.         if (tgetent(tcbuf, tv_stype) != 1)
  925.             fatal("Unknown terminal type", tv_stype);
  926.  
  927.         if ((lines = tgetnum("li")) == -1)
  928.             fatal("Termcap entry incomplete (lines)", tv_stype);
  929.  
  930.         if ((len = tgetnum("co")) == -1)
  931.             fatal("Termcap entry inclomplete (columns)", tv_stype);
  932.  
  933.         p = tcapbuf;
  934.         t = tgetstr("pc", &p);
  935.         if (t)
  936.             PC = *t;
  937.  
  938.         CM = tgetstr("cm", &p); /* cursor movement    */
  939.  
  940.         CL = tgetstr("cl", &p); /* clear screen     */
  941.  
  942.         UP = tgetstr("up", &p); /* cursor up        */
  943.  
  944.         SE = tgetstr("se", &p); /* exit reverse mode    */
  945.  
  946.         SO = tgetstr("so", &p); /* enter reverse mode    */
  947.  
  948.         BC = tgetstr("bc", &p); /* back space char    */
  949.         if (!BC)
  950.             BC = "\010";
  951.  
  952.         DL = tgetstr("dl", &p); /* delete line        */
  953.  
  954.         TI = tgetstr("ti", &p); /* terminal init    */
  955.  
  956.         TE = tgetstr("te", &p); /* terminal reset    */
  957.  
  958.         VS = tgetstr("vs", &p); /* enter visual mode    */
  959.  
  960.         VE = tgetstr("ve", &p); /* exit visual mode    */
  961.  
  962.         KS = tgetstr("ks", &p); /* enter visual mode    */
  963.  
  964.         KE = tgetstr("ke", &p); /* enter visual mode    */
  965.  
  966.         if (!CM || !CL || !UP)
  967.             fatal("Termcap entry incomplete", tv_stype);
  968.  
  969.         for (i = 0; keylist[i].name; i++)
  970.             if ( t = tgetstr(keylist[i].name, &p))
  971.                 fkroot = insertkey(fkroot, t, keylist[i].code);
  972.  
  973.     }
  974. #endif
  975.     if (init)
  976.     {
  977.         con.lline = lines - 1;
  978.         con.lchar = len - 1;
  979.     }
  980. #ifdef AMIGA
  981.     icon_str("\033c");    /* clear screen */
  982. #endif
  983. #ifdef GEMDOS
  984.     icon_str("\033E\033w");        /* cursor on, wrap off */
  985. #endif
  986. #if defined(unix) || defined(OSK)
  987.     if (init)
  988.     {
  989.         if (TI)
  990.             icon_str(TI);
  991.  
  992.         if (VS)
  993.             icon_str(VS);
  994.  
  995.         if (KS)
  996.             icon_str(KS);
  997.     }
  998.     icon_str(CL);
  999. #endif
  1000.     gotoXY(0, con.lline);
  1001.     cursorON();
  1002.     if (init)
  1003.         screen = init_dev(scr_write, con_crlf, 1000, lines, 1);
  1004.  
  1005.     screen->bp = screen->buffer;
  1006.     screen->count = 0;
  1007.     init = 0;
  1008.  
  1009. #ifdef AMIGA
  1010.     ConPutS((UBYTE *)"\23312{\2330 q");
  1011.     con_getc();
  1012. #endif
  1013. }
  1014.  
  1015. /*
  1016. *    open_story        -    open the storyfile specified by the
  1017. *                    global variable story_name
  1018. */
  1019.  
  1020. int open_story()
  1021. {
  1022.     return((story = open(story_name, O_RDONLY)) < 0);
  1023. }
  1024.  
  1025. /*
  1026. *    close_story        -    close the story file
  1027. */
  1028.  
  1029. int close_story()
  1030. {
  1031.     int st;
  1032.     st = close(story);
  1033.     story = -1;
  1034.     return(st);
  1035. }
  1036.  
  1037. /*
  1038. *    read_story(p, n, bp)    -    read n pages (512 byte) from page no. p
  1039. *    unsigned p, n; char *bp;    to the address bp
  1040. */
  1041.  
  1042. void read_story(p, n, bp)
  1043. unsigned p, n; UBYTE *bp;
  1044. {
  1045.     if (read_pages(story, p, n, bp))
  1046.         fatal("story file read error", story_name);
  1047. }
  1048.  
  1049. void read_header(p)
  1050. struct header *p;
  1051. {
  1052.     if (read(story, p, sizeof(struct header)) != sizeof(struct header))
  1053.         fatal("can't read story header", story_name);
  1054. }
  1055.  
  1056. /*
  1057. *    open_save_w(name)    -    open the save file name for writing
  1058. *    char *name;
  1059. */
  1060.  
  1061. int open_save_w(name)
  1062. char *name;
  1063. {
  1064. #ifdef OSK
  1065.     return((save = creat(name, S_IREAD|S_IWRITE)) < 0);
  1066. #else
  1067.     return((save = creat(name, 0666)) < 0);
  1068. #endif
  1069. }
  1070.  
  1071. /*
  1072. *    open_save_r(name)    -    open the save file name for reading
  1073. *    char *name;
  1074. */
  1075.  
  1076. int open_save_r(name)
  1077. char *name;
  1078. {
  1079.     return((save = open(name, O_RDONLY)) < 0);
  1080. }
  1081.  
  1082. /*
  1083. *    close_save()        -    close the save file
  1084. */
  1085.  
  1086. int close_save()
  1087. {
  1088.     int st;
  1089.     st = close(save);
  1090.     save = -1;
  1091. #ifdef OSK
  1092.     return(0);
  1093. #else
  1094.     return(st);
  1095. #endif
  1096. }
  1097.  
  1098. /*
  1099. *    read_save(p, n, bp)    -    read n pages (512 byte) from page no. p
  1100. *    unsigned p, n; char *bp;    to the address bp
  1101. */
  1102.  
  1103. int read_save(p, n, bp)
  1104. unsigned p, n; UBYTE *bp;
  1105. {
  1106.     return(read_pages(save, p, n, bp));
  1107. }
  1108.  
  1109. /*
  1110. *    write_save(p, n, bp)    -    write n pages (512 byte) to page no. p
  1111. *    unsigned p, n; char *bp;    from the address bp
  1112. */
  1113.  
  1114. int write_save(p, n, bp)
  1115. unsigned p, n; UBYTE *bp;
  1116. {
  1117.     return(write_pages(save, p, n, bp));
  1118. }
  1119.  
  1120. /*
  1121. *    write_saveb(p, n, bp)    -    write n bytes to page no. p from the
  1122. *    unsigned p, n; UBYTE *bp;    address bp
  1123. */
  1124.  
  1125. int write_saveb(p, n, bp)
  1126. unsigned p, n; UBYTE *bp;
  1127. {
  1128.     long lseek(), lwrite();
  1129.     if (lseek(save, (long)p * 0x200L, 0) != (long)p * 0x200L)
  1130.         return(1);
  1131.  
  1132.     return(lwrite(save, bp, (long)n) != (long)n);
  1133. }
  1134.  
  1135. /*
  1136. *    read_saveb(p, n, bp)    -    read n bytes from page no. p to the
  1137. *    unsigned p, n; UBYTE *bp;    address bp
  1138. */
  1139.  
  1140. int read_saveb(p, n, bp)
  1141. unsigned p, n; UBYTE *bp;
  1142. {
  1143.     long lseek(), lread();
  1144.     if (lseek(save, (long)p * 0x200L, 0) != (long)p * 0x200L)
  1145.         return(1);
  1146.  
  1147.     return(lread(save, bp, (long)n) < 0L);
  1148. }
  1149.  
  1150. /*
  1151. *    char *read_rname()    -    ask user for restore file
  1152. */
  1153.  
  1154. char *read_rname()
  1155. {
  1156. #ifdef AMIGA
  1157.     extern UBYTE LastFile[256];
  1158.     extern BYTE DontAsk;
  1159.  
  1160.     if(DontAsk && LastFile[0])
  1161.     {
  1162.         DontAsk = FALSE;
  1163.  
  1164.         return((char *)LastFile);
  1165.     }
  1166.     else
  1167.     {
  1168.         DontAsk = FALSE;
  1169.  
  1170.         return((char *)GetRestoreName());
  1171.     }
  1172. #else
  1173.     static char name[129];
  1174.     static struct hist_buf nam_hist = {256, NULL};
  1175.  
  1176.     if (!nam_hist.hb)
  1177.     {
  1178.         if (!(nam_hist.undo = nam_hist.hb = malloc(nam_hist.len)))
  1179.             no_mem_error();
  1180.         else
  1181.         {
  1182.             strcpy(nam_hist.hb,"Story.Save");
  1183.             strcpy(nam_hist.undo,"Story.Save");
  1184.         }
  1185.     }
  1186.  
  1187.     name[0] = 128;
  1188.  
  1189.     con_str1("Insert your save disk then enter a file name.");
  1190.     con_crlf();
  1191.     con_str1("(Default is \"");
  1192.     con_str1(nam_hist.undo);
  1193.     con_str1("\") >");
  1194.     read_str(name, &nam_hist);
  1195.  
  1196.     return(*nam_hist.undo?nam_hist.undo:NULL);
  1197. #endif
  1198. }
  1199.  
  1200. /*
  1201. *    char *read_sname()    -    ask user for save file
  1202. */
  1203.  
  1204. char *read_sname()
  1205. {
  1206. #ifdef AMIGA
  1207.     extern UBYTE LastFile[256];
  1208.     extern BYTE DontAsk;
  1209.  
  1210.     if(DontAsk && LastFile[0])
  1211.     {
  1212.         DontAsk = FALSE;
  1213.  
  1214.         return((char *)LastFile);
  1215.     }
  1216.     else
  1217.     {
  1218.         DontAsk = FALSE;
  1219.  
  1220.         return((char *)GetSaveName());
  1221.     }
  1222. #else
  1223.     char *name;
  1224.     char c;
  1225.     if (name = read_rname())
  1226.     {
  1227.         if (!access(name,0))
  1228.         {
  1229.             con_str1("You are about to write over an existing file. Proceed? (Y/N) ");
  1230.             con_flush();
  1231.  
  1232.             do
  1233.                 c = con_getc();
  1234.             while(c != 'Y' && c != 'N' && c != 'y' && c != 'n');
  1235.  
  1236.             con_chr(c);
  1237.             con_crlf();
  1238.  
  1239.             if (c == 'N' || c == 'n')
  1240.                 return(NULL);
  1241.         }
  1242.         return(name);
  1243.     }
  1244.     else
  1245.         return(NULL);
  1246. #endif
  1247. }
  1248.  
  1249. /*****************************************************************************/
  1250. /*                utility functions                 */
  1251.  
  1252. #ifdef GEMDOS
  1253. long lread(fd, bp, n)
  1254. int fd; UBYTE *bp; long n;
  1255. {
  1256.     return(Fread(fd, n, bp));
  1257. }
  1258.  
  1259. long lwrite(fd, bp, n)
  1260. int fd; UBYTE *bp; long n;
  1261. {
  1262.     return(Fwrite(fd, n, bp));
  1263. }
  1264. #endif
  1265.  
  1266. int write_pages(fd, p, n, bp)
  1267. int fd; unsigned p, n; UBYTE *bp;
  1268. {
  1269.     long lseek();
  1270.     if (lseek(fd, (long)p * 0x200L, 0) != (long)p * 0x200L)
  1271.         return(1);
  1272.  
  1273.     return(lwrite(fd, bp, 0x200L * (long)n) != (0x200L * (long)n));
  1274. }
  1275.  
  1276. int read_pages(fd, p, n, bp)
  1277. int fd; unsigned p, n; UBYTE *bp;
  1278. {
  1279.     if (lseek(fd, (long)p * 0x200L, 0) != (long)p * 0x200L)
  1280.         return(1);
  1281.  
  1282.     return(lread(fd, bp, 0x200L * (long)n) < 0L);
  1283. }
  1284.  
  1285. void icon_str(p)
  1286. register char *p;
  1287. {
  1288. #ifdef AMIGA
  1289.     ConPutS((UBYTE *)p);
  1290. #else
  1291.     while(*p)
  1292. #ifdef GEMDOS
  1293.         Bconout(2,*p++);
  1294. #else    /* GEMDOS */
  1295.         putchar(*p++);
  1296. #endif
  1297. #endif    /* AMIGA */
  1298. }
  1299.  
  1300. void icon_chr(c)
  1301. char c;
  1302. {
  1303. #ifdef AMIGA
  1304.         ConPutC(c);
  1305. #else
  1306. #ifdef GEMDOS
  1307.     Bconout(2,c);
  1308. #else
  1309.     putchar(c);
  1310. #endif
  1311. #endif
  1312. }
  1313.  
  1314. void fatal(s1, s2)
  1315. char *s1, *s2;
  1316. {
  1317. #ifdef AMIGA
  1318.     if (con_is_open)
  1319.     {
  1320.         DPrintf("");
  1321.  
  1322.         if(s2)
  1323.             ConPrintf("ERROR [%s]: %s\n",s2,s1);
  1324.         else
  1325.             ConPrintf("ERROR: %s\n",s2,s1);
  1326.  
  1327.         ConPutS((UBYTE *)"Strike any key to exit.");
  1328.         con_getc();
  1329.     }
  1330.     else
  1331.     {
  1332.         if (StdOut)
  1333.         {
  1334.             if(s2)
  1335.                 FPrintf(StdOut,"ERROR [%s]: %s\n",s2,s1);
  1336.             else
  1337.                 FPrintf(StdOut,"ERROR: %s\n",s2,s1);
  1338.         }
  1339.     }
  1340. #else
  1341.     write(2,": ",2);
  1342.     write(2,s1,strlen(s1));
  1343.     write(2,"ERROR",5);
  1344.     if (s2) {
  1345.         write(2," [",2);
  1346.         write(2,s2,strlen(s2));
  1347.         write(2,"]",1);
  1348.     }
  1349.     write(2,": ",2);
  1350.     write(2,s1,strlen(s1));
  1351. # ifdef GEMDOS
  1352.     write(2,"\n\r",2);
  1353. # else
  1354.     write(2,"\n",1);
  1355. # endif
  1356. #endif
  1357.     clean_up();
  1358.     exit(userexit(1));
  1359. }
  1360.  
  1361. void clean_up()
  1362. {
  1363.     if (story >= 0)
  1364.         close_save();
  1365.  
  1366.     if (save >= 0)
  1367.         close_story();
  1368.  
  1369.     if (pfile >= 0)
  1370.         close(pfile);
  1371.  
  1372. #ifdef AMIGA
  1373.     if (con_is_open)
  1374.         ConCleanup();
  1375. #endif
  1376. #if defined(unix) || defined(OSK)
  1377.     if (TE)
  1378.         icon_str(TE);
  1379.     if (VE)
  1380.         icon_str(VE);
  1381.  
  1382.     if (KE)
  1383.         icon_str(KE);
  1384.  
  1385. #ifdef unix
  1386.     if (ntermio.sg_flags & RAW)
  1387.         ioctl(0, TIOCSETP, &otermio);
  1388. #endif
  1389. #ifdef OSK
  1390.     if (nstate.sg_tabcr == (char)(0x80))
  1391.         stty(0, &ostate);
  1392. #endif
  1393.     icon_chr('\n');
  1394.  
  1395. #endif
  1396. }
  1397.  
  1398. int userexit(s)
  1399. int s;
  1400. {
  1401.     char *getenv();
  1402.  
  1403. #ifdef GEMDOS
  1404.     if (!getenv("ARGV"))
  1405.     {
  1406.         write(2, "\n\rStrike any key to exit ", 24);
  1407.         con_getc();
  1408.     }
  1409. #endif
  1410.     return(s);
  1411. }
  1412.  
  1413. #if defined(unix) || defined(OSK)
  1414. putpad(s)
  1415. char *s;
  1416. {
  1417.     tputs(s, 1, icon_chr);
  1418. }
  1419. #endif
  1420.  
  1421. #if !defined(CADMUS) && !defined(minix)
  1422. char *lmalloc(n)
  1423. long n;
  1424. {
  1425.     return(malloc(n));
  1426. }
  1427. #endif
  1428.  
  1429. #if !defined(minix)
  1430. long lread(a,b,c)
  1431. int a; char *b; int c;
  1432. {
  1433.     return (read(a,b,c));
  1434. }
  1435.  
  1436. long lwrite(a,b,c)
  1437. int a; char *b; int c;
  1438. {
  1439.     return(write(a,b,c));
  1440. }
  1441. #else
  1442. long lread(fd, bp, cnt)
  1443. int fd; char *bp; long cnt;
  1444. {
  1445.     register int n, b;
  1446.     register long bcnt;
  1447.     bcnt = cnt;
  1448.     while(bcnt)
  1449.     {
  1450.         n = read(fd, bp, (int)(b = bcnt>31744?31744:bcnt));
  1451.         if (n < 0)
  1452.             return(n);
  1453.         if (n < b)
  1454.             return(bcnt - n);
  1455.         bcnt -= n;
  1456.         bp += n;
  1457.     }
  1458.     return(cnt);
  1459. }
  1460.  
  1461. long lwrite(fd, bp, cnt)
  1462. int fd; char *bp; long cnt;
  1463. {
  1464.     register int n, b;
  1465.     register long bcnt;
  1466.     bcnt = cnt;
  1467.     while(bcnt)
  1468.     {
  1469.         n = write(fd, bp, (int)(b = bcnt>31744?31744:bcnt));
  1470.         if (n < 0)
  1471.             return(n);
  1472.         if (n < b)
  1473.             return(bcnt - n);
  1474.         bcnt -= n;
  1475.         bp += n;
  1476.     }
  1477.     return(cnt);
  1478. }
  1479.  
  1480. #endif
  1481.